home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-10-28 | 20.9 KB | 816 lines | [TEXT/MPS ] |
- ***********************************************************************
- * *
- * Apple //GS Utility Macros *
- * by *
- * Lou Infeld *
- * *
- * Copyright Apple Computer, Inc. 1986, 1987 *
- * All Rights Reserved *
- * *
- * Revision History *
- * ---------------- *
- * v1.0R1 (04/29/87) -- First Release *
- * This file is a subset of the old *
- * "M16.Utility" *
- * v2.0R1 (01/22/88) -- First AsmIIGS release *
- * v2.0R2 (02/11/88) -- "writelin" renamed "writeline" *
- * v2.0R3 (03/29/88) -- "|" added to pea instrs to avoid Assembler *
- * warning *
- * "pushlong" was incorrect if &offset was "s" *
- * or not specified *
- * v2.0R4 (04/14/88) -- "writestr" and "writeline" didn't restore *
- * STRING setting *
- * v2.0R5 (08/22/88) -- "inc4" and "dec4" redefined to support only *
- * positive 4 byte integers *
- * "sub4" fixed so that there will not be any *
- * truncation warnings generated *
- * Pull macros now check for missing parameter *
- * or extra parameter *
- * v2.0R6 (09/06/88) -- "dec4" fixed to support positive 4 byte *
- * integers *
- * v2.0R7 (4/4/89) -- changed "long" to "longmx", "short" to "shortmx" *
- * and added stack based macros (rls3) *
- *************************************************************************
-
- ;............................................................
- ;
- ; Pull long (4 bytes) from stack
- ;
- ; pulllong address - pull off stack to address
- ; pulllong addr1,addr2 - pull off stack into 2 places
- ; pulllong [zeropage],offset - pull off stack and store indirectly
- ; pulllong - pull off stack and leave in A
- ;...............................................................
- MACRO
- &lab pulllong &addr1,&addr2
- &lab ANOP
- AIF C:&addr1=0,.a
- AIF C:&addr2=0,.b
- LCLC &C
- &C AMID &addr1,1,1
- AIF "&C"="[",.zeropage
- pullword &addr1
- sta &addr2
- pullword &addr1+2
- sta &addr2+2
- MEXIT
- .a
- pullword
- pullword
- MEXIT
- .b
- pullword &addr1
- pullword &addr1+2
- MEXIT
- .zeropage
- ldy #&addr2
- pullword &addr1,y
- ldy #&addr2+2
- pullword &addr1,y
- MEND
- ;...............................................................
- ;
- ; Pull 3 bytes from stack
- ;
- ; pull3 addr -- pulls bytes off stack and stores in "loc"
- ;...............................................................
- MACRO
- &lab pull3 &addr
- &lab ANOP
- pull1 &addr
- pullword &addr+1
- MEND
- ;...............................................................
- ;
- ; Pull 2 bytes from stack
- ;
- ; pullword loc -- pulls bytes off stack and stores in "loc"
- ; pullword loc,x -- pulls bytes off stack and stores in "loc,x"
- ; pullword -- pulls bytes off stack and leaves in A
- ;...............................................................
- MACRO
- &lab pullword &SYSOPR
- &lab ANOP
- pla
- AIF C:&SYSOPR=0,.end
- sta &SYSOPR
- .end
- MEND
- ;...............................................................
- ;
- ; Pull 1 byte from stack
- ;
- ; pull1 loc -- pulls byte off stack and stores in "loc"
- ; pull1 loc,x -- pulls byte off stack and stores in "loc,x"
- ; pull1 -- pulls byte off stack and leaves in A
- ;...............................................................
- MACRO
- &lab pull1 &SYSOPR
- &lab ANOP
- shortm
- pla
- AIF C:&SYSOPR=0,.end
- sta &SYSOPR
- .end
- longm
- MEND
- ;...............................................................
- ;
- ; Push 1 byte onto stack
- ;
- ; push1 loc -- pushes byte onto stack from "loc"
- ; push1 loc,x -- pushes byte onto stack from "loc,x"
- ; push1 #n -- pushes constant #n onto stack
- ; push1 -- pushes byte onto stack (from A)
- ;...............................................................
- MACRO
- &lab push1 &SYSOPR
- &lab ANOP
- shortm
- AIF C:&SYSOPR=0,.a
- pushword &SYSOPR
- AGO .b
- .a
- pushword
- .b
- longm
- MEND
- ;............................................................
- ;
- ; Push long (4 bytes) onto stack
- ;
- ; pushlong address - push contents of address
- ; pushlong address,x - push contents of address,x
- ; pushlong const,s - push contents of stack+const
- ; pushlong #address/const - push address or constant
- ; pushlong [zeropage],offset - push using indirect address
- ;...............................................................
- MACRO
- &lab pushlong &addr,&offset
- &lab ANOP
- LCLC &C
- LCLC &REST
- &C AMID &addr,1,1
- AIF "&C"="#",.immediate
- AIF "&C"="[",.zeropage
- AIF C:&offset=0,.nooffset
- AIF "&offset"="s",.stack
- pushword &addr+2,&offset
- pushword &addr,&offset
- MEXIT
- .nooffset
- pushword &addr+2
- pushword &addr
- MEXIT
- .immediate
- &REST AMID &addr,2,L:&addr-1
- dc I1'$F4',I2'(&REST)|-16'
- dc I1'$F4',I2'&REST'
- MEXIT
- .stack
- pushword &addr+2,s
- pushword &addr+2,s
- MEXIT
- .zeropage
- ldy #&offset+2
- pushword &addr,y
- ldy #&offset
- pushword &addr,y
- MEND
- ;...............................................................
- ;
- ; Push 3 bytes onto stack
- ;
- ; push3 addr -- pushes bytes onto stack from "loc"
- ; push3 addr,x -- pushes bytes onto stack from "loc,x"
- ; push3 #n -- pushes constant #n onto stack
- ;...............................................................
- MACRO
- &lab push3 &addr,®
- &lab ANOP
- LCLC &C
- LCLC &REST
- &C AMID &addr,1,1
- &REST AMID &addr,2,L:&addr
- AIF C:®>0,.indexed
- AIF "&C"="#",.immediate
- lda &addr+1
- pha
- AGO .a
- .immediate
- lda #(&REST)|-8
- pha
- .a
- phb
- lda &addr
- sta 1,s
- MEXIT
- .indexed
- lda &addr+1,®
- pha
- phb
- lda &addr,®
- sta 1,s
- MEND
- ;...............................................................
- ;
- ; Push 2 bytes onto stack
- ;
- ; pushword loc -- pushes bytes onto stack from "loc"
- ; pushword loc,x -- pushes bytes onto stack from "loc,x"
- ; pushword #n -- pushes constant #n onto stack
- ; pushword -- pushes bytes onto stack (from A)
- ;...............................................................
- MACRO
- &lab pushword &SYSOPR
- &lab ANOP
- AIF C:&SYSOPR=0,.b
- LCLC &C
- &C AMID "&SYSOPR",1,1
- AIF ("&C"="#").AND.(S:LONGA),.immediate
- lda &SYSOPR
- pha
- MEXIT
- .b
- pha
- MEXIT
- .immediate
- LCLC &REST
- LCLA &BL
- &BL ASEARCH "&SYSOPR"," ",1
- AIF &BL>0,.a
- &BL SETA L:&SYSOPR+1
- .a
- &REST AMID "&SYSOPR",2,&BL-2
- dc I1'$F4',I2'&REST'
- MEND
- ;...............................................................
- ;
- ; Add 2 byte integers
- ;
- ; add loc1,loc2,loc3 - adds "loc1" to "loc2" and stores in "loc3"
- ; add loc1,loc2 - adds "loc1" to "loc2" and leaves in A
- ; add ,loc2,loc3 - adds A with "loc2" and stores in "loc3"
- ;
- ; "loc1" and "loc2" can be constants
- ;...............................................................
- MACRO
- &lab add &a1,&a2,&a3
- &lab ANOP
- AIF C:&a1=0,.a
- lda &a1
- .a
- clc
- adc &a2
- AIF C:&a3=0,.b
- sta &a3
- .b
- MEND
- ;...............................................................
- ;
- ; Add 4 byte integers
- ;
- ; add4 loc1,loc2,loc3 - adds "loc1" to "loc2" and stores in "loc3"
- ; add4 ,loc2,loc3 - adds A to "loc2" and stores in "loc3"
- ;
- ; "loc1" and "loc2" can be constants
- ;...............................................................
- MACRO
- &lab add4 &a1,&a2,&a3
- &lab ANOP
- LCLC &C1
- LCLC &C2
- LCLC &REST1
- LCLC &REST2
- &C2 AMID &a2,1,1
- &REST2 AMID &a2,2,L:&a2-1
- AIF C:&a1=0,.a
- &C1 AMID &a1,1,1
- &REST1 AMID &a1,2,L:&a1-1
- lda &a1
- .a
- clc
- adc &a2
- sta &a3
- AIF C:&a1>0,.b
- lda #0
- AGO .d
- .b
- AIF "&C1"="#",.c
- lda &a1+2
- AGO .d
- .c
- lda #^&REST1
- .d
- AIF "&C2"="#",.e
- adc &a2+2
- AGO .f
- .e
- adc #^&REST2
- .f
- sta &a3+2
- MEND
- ;...............................................................
- ;
- ; Increment a positive 4 byte integer
- ;
- ; inc4 loc - increments "loc"
- ;...............................................................
- MACRO
- &lab inc4 &a1
- &lab ANOP
- inc &a1
- bne ~a&SYSCNT
- inc &a1+2
- ~a&SYSCNT ANOP
- MEND
- ;...............................................................
- ;
- ; Subtract 2 byte integers
- ;
- ; sub loc1,loc2,loc3 - subtracts "loc2" from "loc1" and stores in "loc3"
- ; sub loc1,loc2 - subtracts "loc2" from "loc1" and leaves in A
- ; sub ,loc2,lo3 - subtracts "loc2" from A and stores in "loc3"
- ;
- ; "loc1" and "loc2" can be constants
- ;...............................................................
- MACRO
- &lab sub &a1,&a2,&a3
- &lab ANOP
- AIF C:&a1=0,.a
- lda &a1
- .a
- sec
- sbc &a2
- AIF C:&a3=0,.b
- sta &a3
- .b
- MEND
- ;...............................................................
- ;
- ; Subtract 4 byte integers
- ;
- ; sub4 loc1,loc2,loc3 - subtracts "loc2" from "loc1" and stores in "loc3"
- ; sub4 ,loc2,loc3 - subtracts "loc2" from A and stores in "loc3"
- ;...............................................................
- MACRO
- &lab sub4 &a1,&a2,&a3
- &lab ANOP
- LCLC &C1
- LCLC &C2
- LCLC &REST1
- LCLC &REST2
- &C2 AMID &a2,1,1
- &REST2 AMID &a2,2,L:&a2-1
- AIF C:&a1=0,.a
- &C1 AMID &a1,1,1
- &REST1 AMID &a1,2,L:&a1-1
- lda &a1
- .a
- sec
- sbc &a2
- sta &a3
- AIF C:&a1>0,.b
- lda #0
- AGO .d
- .b
- AIF "&C1"="#",.c
- lda &a1+2
- AGO .d
- .c
- lda #^&REST1
- .d
- AIF "&C2"="#",.e
- sbc &a2+2
- AGO .f
- .e
- sbc #^&REST2
- .f
- sta &a3+2
- MEND
- ;...............................................................
- ;
- ; Decrement a positive 4 byte integer
- ;
- ; dec4 loc - decrements "loc"
- ;...............................................................
- MACRO
- &lab dec4 &a1
- &lab ANOP
- pha
- sec
- lda &a1
- sbc #1
- bcs ~a&SYSCNT
- dec &a1+2
- ~a&SYSCNT sta &a1
- pla
- MEND
- ;...............................................................
- ;
- ; Define string
- ;
- ; Generates a Pascal type of string
- ;...............................................................
- MACRO
- &lab str &string
- &lab dc i1'L:&string',C'&string'
- MEND
- ;...............................................................
- ;
- ; Define pointer
- ;...............................................................
- MACRO
- &lab dp &pointer
- &lab dc i4'&pointer'
- MEND
- ;...............................................................
- ;
- ; Left Shift 4 bytes
- ;
- ; asl4 loc,#n ;n is shift count (pos)
- ; asl4 loc,lnum ;lnum contains shift count (pos)
- ; asl4 loc ;X contains shift count (pos)
- ;...............................................................
- MACRO
- &lab asl4 &loc,&num
- &lab ANOP
- lda &loc+2
- AIF C:&num=0,.a
- ldx &num
- .a
- ~a&SYSCNT asl a
- asl &loc
- adc #0
- dex
- bne ~a&SYSCNT
- sta &loc+2
- MEND
- ;...............................................................
- ;
- ; Right Shift 4 bytes
- ;
- ; lsr4 loc,#n ;n is shift count (pos)
- ; lsr4 loc,lnum ;lnum contains shift count (pos)
- ; lsr4 loc ;X contains shift count (neg)
- ;...............................................................
- MACRO
- &lab lsr4 &loc,&num
- &lab ANOP
- AIF C:&num=0,.a
- lda &num
- eor #$FFFF
- clc
- adc #1
- tax
- .a
- lda &loc
- ~a&SYSCNT lsr a
- lsr &loc+2
- bcc ~b&SYSCNT
- ora #$8000
- ~b&SYSCNT inx
- bne ~a&SYSCNT
- sta &loc
- MEND
- ;...............................................................
- ;
- ; Turn on native mode
- ;
- ; The processor is put into "native" mode. 8 bit or 16 bit
- ; mode can be specified by using "shortmx" or "longmx" as the
- ; parameter. If no parameter is specified, "long" is assumed
- ;...............................................................
- MACRO
- &lab native &mode
- &lab ANOP
- clc
- xce
- AIF C:&mode=0,.a
- &mode
- MEXIT
- .a
- longmx
- MEND
- ;...............................................................
- ;
- ; Turn on emulation mode
- ;
- ; The processor is put into "emulation" mode.
- ;...............................................................
- MACRO
- &lab emulation
- &lab ANOP
- sec
- xce
- longa off
- longi off
- MEND
- ;...............................................................
- ;
- ; Set Memory & registers to 16 bits
- ;...............................................................
- MACRO
- &lab longmx
- &lab ANOP
- rep #%00110000
- longa on
- longi on
- MEND
- ;...............................................................
- ;
- ; Set Memory & A register to 16 bits
- ;...............................................................
- MACRO
- &lab longm
- &lab ANOP
- rep #%00100000
- longa on
- MEND
- ;...............................................................
- ;
- ; Set X & Y registers to 16 bits
- ;...............................................................
- MACRO
- &lab longx
- &lab ANOP
- rep #%00010000
- longi on
- MEND
- ;...............................................................
- ;
- ; Set Memory & registers to 8 bits
- ;...............................................................
- MACRO
- &lab shortmx
- &lab ANOP
- sep #%00110000
- longa off
- longi off
- MEND
- ;...............................................................
- ;
- ; Set Memory & A register to 8 bits
- ;...............................................................
- MACRO
- &lab shortm
- &lab ANOP
- sep #%00100000
- longa off
- MEND
- ;...............................................................
- ;
- ; Set X & Y registers to 8 bits
- ;...............................................................
- MACRO
- &lab shortx
- &lab ANOP
- sep #%00010000
- longi off
- MEND
- ;...............................................................
- ;
- ; Write string
- ;
- ; writestr loc - string at loc "loc"
- ; writestr #'ABC' - string='ABC'
- ; writestr - A,Y has loc of string
- ;...............................................................
-
- MACRO
- &lab writestr &addr
- &lab ANOP
- AIF C:&addr=0,.c
- lclc &char
- &char amid &addr,1,1
- AIF "&char"="#",.a
- pea &addr|-16
- pea &addr
- ago .b
- .a
- lclc &str
- &str amid &addr,3,L:&addr-3
- bra ~b&SYSCNT
- ~a&SYSCNT dc i1'L:&str',C'&str'
- ~b&SYSCNT pea ~a&SYSCNT|-16
- pea ~a&SYSCNT
- .b
- ldx #$1C0C
- jsl $E10000
- MEXIT
- .c
- phy
- pha
- AGO .b
- MEND
- ;...............................................................
- ;
- ; Write line (string+CR)
- ;
- ; writeln loc - string at loc "loc"
- ; writeln #'ABC' - string='ABC'
- ; writeln - CR only
- ;
- ;...............................................................
-
- MACRO
- &lab writeln &addr
- &lab ANOP
- AIF C:&addr=0,.c
- lclc &char
- &char amid &addr,1,1
- AIF "&char"="#",.a
- pea &addr|-16
- pea &addr
- ago .b
- .a
- lclc &str
- &str amid &addr,3,L:&addr-3
- bra ~b&SYSCNT
- ~a&SYSCNT dc I1'L:&str',C'&str'
- ~b&SYSCNT pea ~a&SYSCNT|-16
- pea ~a&SYSCNT
- .b
- ldx #$1A0C
- ~c&SYSCNT jsl $E10000
- MEXIT
- .c
- pea +(~c&SYSCNT+1)|-16
- pea ~c&SYSCNT+1
- AGO .b
- MEND
- ;...............................................................
- ;
- ; Write character
- ;
- ; writech - char in A register
- ; writech #'A' - char='A'
- ; writech ch,x - char in loc "ch,x"
- ;...............................................................
-
- MACRO
- &lab writech &SYSOPR
- &lab ANOP
- AIF C:&SYSOPR=0,.a
- lda &SYSOPR
- .a
- pha
- ldx #$180C
- jsl $E10000
- MEND
- ;...............................................................
- ;
- ; Read a char from keyboard
- ;
- ; readch addr - char stored in "addr"
- ; readch - char left in A register
- ;
- ;...............................................................
-
- MACRO
- &lab readch &SYSOPR
- &lab ANOP
- pea 0
- pea 1
- ldx #$220C
- jsl $E10000
- pla
- AIF C:&SYSOPR=0,.a
- sta &SYSOPR
- .a
- MEND
-
- ;
- ; DSect &Value
- ;
- ; Begin local data section. This defines a dummy PC
- ; register which can be used in equates to avoid error-
- ; prone linked equates for setting up direct page or
- ; stack offsets. The dummy PC begins at &Value and
- ; is updated by the appropriate amount by the BYTE,
- ; WORD, LONG, and BLOCK macros.
- ;
- MACRO
- DSect &Value
- GBLA &DummyPC
- &DummyPC SETA &Value
- MEND
-
-
- ;
- ; DefineStack
- ;
- ; This is a specialized data section which defines
- ; a dummy PC starting at 1 in order to define a
- ; series of stack offsets using the BYTE, WORD,
- ; LONG, and BLOCK macros.
- ;
- MACRO
- DefineStack
- GBLA &DummyPC
- &DummyPC SETA 1
- MEND
-
- ;
- ; &lab byte
- ;
- ; Equate the given label with the current dummy
- ; PC (defined by DSect, GlobalDSect, or
- ; DefineStack), and update the dummy PC by the
- ; appropriate amount.
- ;
- MACRO
- &lab BYTE
- &lab equ &DummyPC
- &DummyPC SETA &DummyPC+1
- MEND
-
- ;
- ; &lab word
- ;
- ; Equate the given label with the current dummy
- ; PC (defined by DSect, GlobalDSect, or
- ; DefineStack), and update the dummy PC by the
- ; appropriate amount.
- ;
- MACRO
- &lab WORD
- &lab equ &DummyPC
- &DummyPC SETA &DummyPC+2
- MEXIT
- MEND
-
- ;
- ; &lab long
- ;
- ; Equate the given label with the current dummy
- ; PC (defined by DSect, GlobalDSect, or
- ; DefineStack), and update the dummy PC by the
- ; appropriate amount.
- ;
- MACRO
- &lab LONG
- &lab equ &DummyPC
- &DummyPC SETA &DummyPC+4
- MEND
-
- ;
- ; &lab block &size
- ;
- ; Equate the given label with the current dummy
- ; PC (defined by DSect, GlobalDSect, or
- ; DefineStack), and update the dummy PC by the
- ; appropriate amount (&size bytes).
- ;
- MACRO
- &lab BLOCK &Value
- AIF C:&lab=0,.skiplab
- &lab equ &DummyPC
- .skiplab
- &DummyPC SETA &DummyPC+&Value
- MEND
-
- ;
- ; &lab DSectSize
- ;
- ; This macro equates the given label with the
- ; current dummy PC defined by the DSect,
- ; GlobalDSect, or DefineStack macros. This is
- ; useful for determing the size of data sections
- ; or parts of data sections.
- ;
- MACRO
- &lab DSectSize
- &lab equ &DummyPC
- MEND
-
- ;
- ; &lab EndLocals
- ;
- ; This macro equates the given label with the
- ; current DummyPC-1 defined by the DSect,
- ; GlobalDSect, or DefineStack macros. This is
- ; useful for determing the stack usage of locals.
- ;
- MACRO
- &lab EndLocals
- &lab equ &DummyPC-1
- MEND
-
- ;
- ; BegParms - description to be supplied at a future date.
- ;
- MACRO
- BegParms
- &BegParmsPC SETA &DummyPC
- MEND
-
- ;
- ; EndParms - description to be supplied at a future date.
- ;
- MACRO
- &lab EndParms
- &lab equ &DummyPC-&BegParmsPC
- MEND
-
-